Next: Putting it Together, Previous: Using \eqref, Up: Defining Label Environments [Contents][Index]
Some LaTeX packages define environment-like structures without
using the standard ‘\begin..\end’
structure. RefTeX cannot parse these directly, but you can write
your own special-purpose parser and use it instead of the name of
an environment in an entry for reftex-label-alist.
The function should check if point is currently in the special
environment it was written to detect. If so, it must return a
buffer position indicating the start of this environment. The
return value must be nil on failure to detect the
environment. The function is called with one argument
bound. If non-nil, bound is a
boundary for backwards searches which should be observed. We will
discuss two examples.
Some people define abbreviations for environments, like
\be for \begin{equation}, and
\ee for \end{equation}. The parser
function would have to search backward for these macros. When the
first match is \ee, point is not in this
environment. When the first match is \be, point is
in this environment and the function must return the beginning of
the match. To avoid scanning too far, we can also look for empty
lines which cannot occur inside an equation environment. Here is
the setup:
;; Setup entry in reftex-label-alist, using all defaults for equations
(setq reftex-label-alist '((detect-be-ee ?e nil nil nil nil)))
(defun detect-be-ee (bound)
;; Search backward for the macros or an empty line
(if (re-search-backward
"\\(^[ \t]*\n\\|\\\\ee\\>\\)\\|\\(\\\\be\\>\\)" bound t)
(if (match-beginning 2)
(match-beginning 2) ; Return start of environment
nil) ; Return nil because env is closed
nil)) ; Return nil for not found
A more complex example is the linguex.sty package which defines list macros ‘\ex.’, ‘\a.’, ‘\b.’ etc. for lists which are terminated by ‘\z.’ or by an empty line.
\ex. \label{ex:12} Some text in an exotic language ...
\a. \label{ex:13} more stuff
\b. \label{ex:14} still more stuff
\a. List on a deeper level
\b. Another item
\b. and the third one
\z.
\b. Third item on this level.
... text after the empty line terminating all lists
The difficulty is that the ‘\a.’ lists can nest and that an empty line terminates all list levels in one go. So we have to count nesting levels between ‘\a.’ and ‘\z.’. Here is the implementation for RefTeX.
(setq reftex-label-alist
'((detect-linguex ?x "ex:" "~\\ref{%s}" nil ("Example" "Ex."))))
(defun detect-linguex (bound)
(let ((cnt 0))
(catch 'exit
(while
;; Search backward for all possible delimiters
(re-search-backward
(concat "\\(^[ \t]*\n\\)\\|\\(\\\\z\\.\\)\\|"
"\\(\\ex[ig]?\\.\\)\\|\\(\\\\a\\.\\)")
nil t)
;; Check which delimiter was matched.
(cond
((match-beginning 1)
;; empty line terminates all - return nil
(throw 'exit nil))
((match-beginning 2)
;; \z. terminates one list level - decrease nesting count
(decf cnt))
((match-beginning 3)
;; \ex. : return match unless there was a \z. on this level
(throw 'exit (if (>= cnt 0) (match-beginning 3) nil)))
((match-beginning 4)
;; \a. : return match when on level 0, otherwise
;; increment nesting count
(if (>= cnt 0)
(throw 'exit (match-beginning 4))
(incf cnt))))))))
Next: Putting it Together, Previous: Using \eqref, Up: Defining Label Environments [Contents][Index]